﻿using System;
using System.Collections.Generic;
using System.Linq;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Architecture;
using Autodesk.Revit.DB.ExtensibleStorage;
using Autodesk.Revit.Exceptions;
using YJKSparseDistance.ModelLayer;
using YJKSparseDistance.Properties;
using YJKRoomInspection.Utiltiy;
using YJKGeometryFuncs;
using YJKGeometryFuncs.CurveUtility;
using YJKInspectModelFunc;
using YJKInspectModelFunc.ModelLayer;

namespace YJKSparseDistance
{
	public static class Utility
	{
		public static bool IfResultBeanTrusted(Area inputArea, ResultBean inputBean, string strGuid)
		{
			List<string> allValues;
			Entity entity;
			return InsetDataUtility.TryGetAddedValue(strGuid, inputArea, out allValues, out entity) && YJKSparseDistance.Utility.IfResultTrusted(inputBean, allValues);
		}

		public static List<Curve> GetAllCurvesInOneBox(List<Curve> input, XYZ pointOne, XYZ pointTwo, double tolerance = 4.0)
		{
			List<Curve> list = new List<Curve>();
			double num = pointOne.DistanceTo(pointTwo);
			double[] array = new double[2];
			double[] array2 = new double[2];
			foreach (Curve curve in input)
			{
				array[0] = YJKSparseDistance.Utility.MinDistanceOfCurveToPoint(curve, pointOne, out array2[0]);
				array[1] = YJKSparseDistance.Utility.MinDistanceOfCurveToPoint(curve, pointTwo, out array2[1]);
				if (array.Sum() + array2.Sum() <= tolerance * num)
				{
					list.Add(curve);
				}
			}
			return list;
		}

		public static double MinDistanceOfCurveToPoint(Curve inputCurve, XYZ inputPoint, out double maxValue)
		{
			double num = double.MaxValue;
			maxValue = double.MinValue;
			XYZ curveMidPoint = YJKSparseDistance.Utility.GetCurveMidPoint(inputCurve);
			num = Math.Min(inputCurve.GetEndPoint(0).DistanceTo(inputPoint), num);
			maxValue = Math.Max(inputCurve.GetEndPoint(0).DistanceTo(inputPoint), maxValue);
			num = Math.Min(inputCurve.GetEndPoint(1).DistanceTo(inputPoint), num);
			maxValue = Math.Max(inputCurve.GetEndPoint(1).DistanceTo(inputPoint), maxValue);
			num = Math.Min(curveMidPoint.DistanceTo(inputPoint), num);
			maxValue = Math.Max(curveMidPoint.DistanceTo(inputPoint), maxValue);
			return num;
		}

		public static double GetFullAngleToBasisX(ResultBean inputValue, int useIndex)
		{
			return inputValue.LstPoints[useIndex + 1].Add(-inputValue.LstPoints[useIndex]).Normalize().FullAngleToBasisXAtXoY();
		}

		public static List<RoomPacker_EvacuationDistance> FindAllStairRooms(List<BaseRoomPacker> inputRooms, List<int> lstFrontRoomStairIds)
		{
			List<RoomPacker_EvacuationDistance> list = new List<RoomPacker_EvacuationDistance>();
			bool flag = false;
			bool flag2 = false;
			for (int i = 0; i < inputRooms.Count; i++)
			{
				flag = false;
				flag2 = false;
				if (inputRooms[i] is RoomPacker_EvacuationDistance)
				{
					RoomPacker_EvacuationDistance roomPacker_EvacuationDistance = inputRooms[i] as RoomPacker_EvacuationDistance;
					if (roomPacker_EvacuationDistance != null)
					{
						foreach (KeyValuePair<BaseHostInRoomPacker, XYZ> keyValuePair in roomPacker_EvacuationDistance.LstHostElementPacker)
						{
							if (keyValuePair.Key is ObstructurePacker_EvacuationDistance && keyValuePair.Key is ObstructurePacker_EvacuationDistance)
							{
								if ((keyValuePair.Key as ObstructurePacker_EvacuationDistance).IfStairs)
								{
									flag2 = true;
								}
								if (lstFrontRoomStairIds.Contains(keyValuePair.Key.ThisElementPackerId))
								{
									roomPacker_EvacuationDistance.ThisKindEnum = StairRoomKindEnum.Smoke;
									flag = true;
									list.Add(roomPacker_EvacuationDistance);
									break;
								}
							}
						}
						if (!flag && roomPacker_EvacuationDistance.LstHostElementPacker.Count > 0)
						{
							list.Add(roomPacker_EvacuationDistance);
							if (flag2)
							{
								if (YJKRoomInspection.Utiltiy.Utility.JudgeStairRoomByArea(roomPacker_EvacuationDistance.UseDocument, roomPacker_EvacuationDistance))
								{
									roomPacker_EvacuationDistance.ThisKindEnum = StairRoomKindEnum.Close;
								}
								else
								{
									roomPacker_EvacuationDistance.ThisKindEnum = StairRoomKindEnum.Open;
								}
							}
						}
					}
				}
			}
			list = list.Distinct<RoomPacker_EvacuationDistance>().ToList<RoomPacker_EvacuationDistance>();
			return list;
		}

		public static List<RoomPacker_EvacuationDistance> FindAllRunWayRooms(List<BaseRoomPacker> inputRooms, List<ICloseCurveAnalays> inputCloseCurveAnalays, bool ifNeedArea = true)
		{
			List<int> frontRoomStairIds = YJKSparseDistance.Utility.GetFrontRoomStairIds(inputCloseCurveAnalays);
			return YJKSparseDistance.Utility.FindAllRunWayRooms(YJKSparseDistance.Utility.FindAllStairRooms(inputRooms, frontRoomStairIds), inputCloseCurveAnalays, inputRooms, ifNeedArea);
		}

		public static List<RoomPacker_EvacuationDistance> FindAllRunWayRooms(List<RoomPacker_EvacuationDistance> lstStairRooms, List<ICloseCurveAnalays> inputCloseCurveAnalays, List<BaseRoomPacker> lstAllRoomPacker, bool ifNeedArea = true)
		{
			List<RoomPacker_EvacuationDistance> list = new List<RoomPacker_EvacuationDistance>();
			foreach (RoomPacker_EvacuationDistance input in lstStairRooms)
			{
				list.AddRange(YJKSparseDistance.Utility.FindRunWayRoom(input));
			}
			foreach (ICloseCurveAnalays input2 in inputCloseCurveAnalays)
			{
				list.AddRange(YJKSparseDistance.Utility.FindRunWayRoom(input2));
			}
			for (int i = 0; i < lstAllRoomPacker.Count; i++)
			{
				if (lstAllRoomPacker[i] is RoomPacker_EvacuationDistance)
				{
					RoomPacker_EvacuationDistance roomPacker_EvacuationDistance = lstAllRoomPacker[i] as RoomPacker_EvacuationDistance;
					if (roomPacker_EvacuationDistance != null && roomPacker_EvacuationDistance.IfIsRunWayRoomByName)
					{
						roomPacker_EvacuationDistance.SetAsRunWayRoom();
						list.Add(roomPacker_EvacuationDistance);
					}
				}
			}
			list = list.Distinct<RoomPacker_EvacuationDistance>().ToList<RoomPacker_EvacuationDistance>();
			if (ifNeedArea)
			{
				list = (from n in list
				where n.ParentAreaPacker != null
				select n).ToList<RoomPacker_EvacuationDistance>();
			}
			return list;
		}

		private static List<int> GetFrontRoomStairIds(List<ICloseCurveAnalays> inputCloseCurveAnalays)
		{
			List<int> result = new List<int>();
			foreach (ICloseCurveAnalays inputValue in inputCloseCurveAnalays)
			{
				YJKSparseDistance.Utility.AddFrontRoomStairIdInList(inputValue, ref result);
			}
			return result;
		}

		public static void AddFrontRoomStairIdInList(ICloseCurveAnalays inputValue, ref List<int> lstNeedInput)
		{
			if (lstNeedInput == null)
			{
				lstNeedInput = new List<int>();
			}
			foreach (BaseRoomPacker baseRoomPacker in inputValue.GetNearRooms())
			{
				foreach (KeyValuePair<BaseHostInRoomPacker, XYZ> keyValuePair in baseRoomPacker.LstHostElementPacker)
				{
					if (keyValuePair.Key is ObstructurePacker_EvacuationDistance && keyValuePair.Key is ObstructurePacker_EvacuationDistance && (keyValuePair.Key as ObstructurePacker_EvacuationDistance).IfStairs && YJKRoomInspection.Utiltiy.Utility.JudgeStairRoomByArea(baseRoomPacker.UseDocument, baseRoomPacker))
					{
						lstNeedInput.Add(baseRoomPacker.ThisElementPackerId);
					}
				}
			}
		}

		public static List<RoomPacker_EvacuationDistance> FindRunWayRoom(RoomPacker_EvacuationDistance input)
		{
			List<RoomPacker_EvacuationDistance> list = new List<RoomPacker_EvacuationDistance>();
			if (input.ThisKindEnum == StairRoomKindEnum.Close)
			{
				using (List<BaseRoomPacker>.Enumerator enumerator = input.LstNearBaseRoomPacker.GetEnumerator())
				{
					while (enumerator.MoveNext())
					{
						BaseRoomPacker baseRoomPacker = enumerator.Current;
						if (baseRoomPacker is RoomPacker_EvacuationDistance && baseRoomPacker is RoomPacker_EvacuationDistance)
						{
							list.Add(baseRoomPacker as RoomPacker_EvacuationDistance);
							list[list.Count - 1].SetAsRunWayRoom(input);
						}
					}
					return list;
				}
			}
			if (input.ThisKindEnum == StairRoomKindEnum.Open)
			{
				list.Add(input);
				input.SetAsRunWayRoom(input);
			}
			return list;
		}

		public static List<RoomPacker_EvacuationDistance> FindRunWayRoom(ICloseCurveAnalays input)
		{
			List<RoomPacker_EvacuationDistance> list = new List<RoomPacker_EvacuationDistance>();
			List<BaseDoorPacker> doorsFromCloseCurve = YJKRoomInspection.Utiltiy.Utility.GetDoorsFromCloseCurve(input);
			if (doorsFromCloseCurve != null)
			{
				List<BaseRoomPacker> nearRooms = input.GetNearRooms();
				foreach (BaseDoorPacker baseDoorPacker in doorsFromCloseCurve)
				{
					foreach (BaseRoomPacker baseRoomPacker in baseDoorPacker.LstConctRooms)
					{
						if (nearRooms.Contains(baseRoomPacker))
						{
							list.Add(baseRoomPacker as RoomPacker_EvacuationDistance);
							list[list.Count - 1].SetAsRunWayRoom(baseDoorPacker);
						}
					}
				}
			}
			list = list.Distinct<RoomPacker_EvacuationDistance>().ToList<RoomPacker_EvacuationDistance>();
			return list;
		}

		public static bool IfResultTrusted(ResultBean input, List<string> allValues)
		{
			double val = 0.0;
			foreach (string text in allValues)
			{
				string[] array = text.Split(new char[]
				{
					':'
				});
				if (array.Length >= 3 && input.StartPoint.ToString().Equals(array[0]) && input.EndPoint.ToString().Equals(array[1]) && double.TryParse(array[2], out val) && Geometry.IsEqual(input.Distance, val, 0.05))
				{
					return true;
				}
			}
			return false;
		}

		public static bool IfTwoCurveCanContinueIntersect(Curve inputCurveOne, Curve inputCurveTwo)
		{
			CurveBoundingXYPlane curveBoundingXYPlane = new CurveBoundingXYPlane(inputCurveOne);
			CurveBoundingXYPlane curveBoundingXYPlane2 = new CurveBoundingXYPlane(inputCurveTwo);
			return curveBoundingXYPlane.IfCanUse && curveBoundingXYPlane2.IfCanUse && (curveBoundingXYPlane.minX > curveBoundingXYPlane2.maxX + 0.1 || curveBoundingXYPlane.maxX < curveBoundingXYPlane2.minX - 0.1 || curveBoundingXYPlane.minY > curveBoundingXYPlane2.maxY + 0.1 || curveBoundingXYPlane2.maxY < curveBoundingXYPlane2.minY - 0.1);
		}

		public static Curve ExtendCurve(Curve input, double extendValue)
		{
			double endParameter = input.GetEndParameter(0);
			double endParameter2 = input.GetEndParameter(1);
			double num = endParameter - (endParameter2 - endParameter) * (extendValue / input.Length);
			double num2 = endParameter2 + (endParameter2 - endParameter) * (extendValue / input.Length);
			Curve curve = input.Clone();
			curve.MakeUnbound();
			curve.MakeBound(num, num2);
			return curve;
		}

		public static StairsRun GetANearestStairsRun(Stairs input, double useZ, Transform useTransform = null)
		{
			if (input == null)
			{
				return null;
			}
			Document document = input.Document;
			List<StairsRun> list = new List<StairsRun>();
			foreach (ElementId elementId in input.GetStairsRuns())
			{
				list.Add(document.GetElement(elementId) as StairsRun);
			}
			double num = double.MaxValue;
			double num2 = 0.0;
			StairsRun result = null;
			if (useTransform != null)
			{
				num2 = YJKSparseDistance.Utility.GetATransformEffectOnZAxisx(useTransform);
			}
			foreach (StairsRun stairsRun in list)
			{
				double num3 = 0.5 * (stairsRun.TopElevation + stairsRun.BaseElevation + 2.0 * num2);
				if (Math.Abs(num3 - useZ) < num)
				{
					num = Math.Abs(num3 - useZ);
					result = stairsRun;
				}
			}
			return result;
		}

		public static double GetATransformEffectOnZAxisx(Transform input)
		{
			XYZ zero = XYZ.Zero;
			return Geometry.TransformPoint(zero, input).Z - zero.Z;
		}

		public static double FullAngleToBasisXAtXoY(this XYZ inputValue)
		{
			double num = inputValue.AngleTo(XYZ.BasisX);
			if (inputValue.Y < XYZ.BasisX.Y)
			{
				num = -num;
			}
			return num;
		}

		public static List<Curve> GetAllFreeEndLink(List<BaseCurvePacker> inputValue)
		{
			List<Curve> list = new List<Curve>();
			List<BaseCurvePacker> list2 = (from k in inputValue
			where k.IfFreeEnd
			select k).ToList<BaseCurvePacker>();
			for (int i = 0; i < list2.Count; i++)
			{
				for (int j = 0; j < list2.Count; j++)
				{
					if (i < j)
					{
						if (list2[i] is BulidingCurvePakcer && list2[j] is BulidingCurvePakcer)
						{
							BulidingCurvePakcer bulidingCurvePakcer = list2[i] as BulidingCurvePakcer;
							BulidingCurvePakcer bulidingCurvePakcer2 = list2[j] as BulidingCurvePakcer;
							if (bulidingCurvePakcer != null && bulidingCurvePakcer2 != null && !YJKSparseDistance.Utility.IfIsSameElementBoundary(bulidingCurvePakcer, bulidingCurvePakcer2))
							{
								list.AddRange(YJKSparseDistance.Utility.GetAllEndLinkCurve(list2[i].ThisCurve, list2[j].ThisCurve));
							}
						}
						else
						{
							list.AddRange(YJKSparseDistance.Utility.GetAllEndLinkCurve(list2[i].ThisCurve, list2[j].ThisCurve));
						}
					}
				}
			}
			return list;
		}

		public static List<Curve> GetAllFreeEndLink(List<XYZ> input, double tolerance)
		{
			List<Curve> list = new List<Curve>();
			for (int i = 0; i < input.Count; i++)
			{
				XYZ xyz = input[i];
				for (int j = 0; j < input.Count; j++)
				{
					if (i < j)
					{
						XYZ xyz2 = input[j];
						if (!xyz.IsAlmostEqualTo(xyz2, tolerance))
						{
							try
							{
								Line item = Line.CreateBound(xyz, xyz2);
								list.Add(item);
							}
							catch (ArgumentsInconsistentException)
							{
							}
						}
					}
				}
			}
			return list;
		}

		private static bool IfIsSameElementBoundary(BulidingCurvePakcer tempBuildingPackerOne, BulidingCurvePakcer tempBuildingPackerTwo)
		{
			return tempBuildingPackerOne.UseElementId == tempBuildingPackerTwo.UseElementId && tempBuildingPackerOne.UseLinkedInstanceId == tempBuildingPackerTwo.UseLinkedInstanceId && -1 != tempBuildingPackerOne.UseElementId && -1 != tempBuildingPackerTwo.UseElementId;
		}

		public static List<Curve> GetAllEndLinkCurve(Curve curveOne, Curve curveTwo)
		{
			List<Curve> list = new List<Curve>();
			for (int i = 0; i < 2; i++)
			{
				for (int j = 0; j < 2; j++)
				{
					if (!curveOne.GetEndPoint(i).IsAlmostEqualTo(curveTwo.GetEndPoint(j)))
					{
						try
						{
							list.Add(Line.CreateBound(curveOne.GetEndPoint(i), curveTwo.GetEndPoint(j)));
						}
						catch (ArgumentsInconsistentException)
						{
						}
					}
				}
			}
			if (list.Count >= 3)
			{
				list = (from k in list
				orderby k.Length
				select k).ToList<Curve>();
				list = new List<Curve>
				{
					list[0],
					list[1]
				};
			}
			return list;
		}

		public static bool IfIntersectionAtEnd(Curve inputCurve, IntersectionResult inputResult)
		{
			return inputCurve.GetEndPoint(0).IsAlmostEqualTo(inputResult.XYZPoint) || inputCurve.GetEndPoint(1).IsAlmostEqualTo(inputResult.XYZPoint);
		}

		public static List<Curve> CutCurveFromMid(Curve inputValue, double midFactory, out List<XYZ> freeEnds)
		{
			List<Curve> list = new List<Curve>();
			Curve curve = inputValue.Clone();
			Curve curve2 = inputValue.Clone();
			freeEnds = new List<XYZ>();
			double endParameter = inputValue.GetEndParameter(0);
			double endParameter2 = inputValue.GetEndParameter(1);
			double num = (endParameter2 + endParameter) / 2.0;
			double num2 = num - (endParameter2 - endParameter) * midFactory / 2.0;
			double num3 = num + (endParameter2 - endParameter) * midFactory / 2.0;
			curve.MakeBound(endParameter, num2);
			curve2.MakeBound(num3, endParameter2);
			list.Add(curve);
			list.Add(curve2);
			freeEnds.Add(inputValue.Evaluate(num2, false));
			freeEnds.Add(inputValue.Evaluate(num3, false));
			return list;
		}

		public static List<Curve> MakeEndCurves(Curve inputCurveOne, Curve inputCurveTwo)
		{
			List<Curve> list = new List<Curve>();
			if (null != inputCurveOne && null != inputCurveTwo)
			{
				Curve curve = inputCurveOne.Clone();
				Curve curve2 = inputCurveTwo.Clone();
				if (YJKSparseDistance.Utility.IfCurveEndSameDirection(curve, curve2))
				{
					list.Add(Line.CreateBound(curve.GetEndPoint(0), curve2.GetEndPoint(0)));
					list.Add(Line.CreateBound(curve.GetEndPoint(1), curve2.GetEndPoint(1)));
				}
				else
				{
					list.Add(Line.CreateBound(curve.GetEndPoint(1), curve2.GetEndPoint(0)));
					list.Add(Line.CreateBound(curve.GetEndPoint(0), curve2.GetEndPoint(1)));
				}
			}
			return list;
		}

		public static bool IfCurveEndSameDirection(Curve useCurveOne, Curve useCurveTwo)
		{
			return YJKSparseDistance.Utility.DistanceNonZValue(useCurveOne.GetEndPoint(0), useCurveTwo.GetEndPoint(0)) < YJKSparseDistance.Utility.DistanceNonZValue(useCurveOne.GetEndPoint(0), useCurveTwo.GetEndPoint(1));
		}

		public static double DistanceNonZValue(Curve tempCurve, BaseDoorPacker tempDoorPacker)
		{
			return YJKSparseDistance.Utility.DistanceNonZValue(tempDoorPacker.ThisLimitGeometryPacker.CenterPoint, YJKSparseDistance.Utility.GetCurveMidPoint(tempCurve));
		}

		public static double DistanceNonZValue(XYZ pointOne, XYZ pointTwo)
		{
			XYZ xyz = new XYZ(pointOne.X, pointOne.Y, 0.0);
			XYZ xyz2 = new XYZ(pointTwo.X, pointTwo.Y, 0.0);
			return xyz.DistanceTo(xyz2);
		}

		public static List<Curve> GetCutedLstCurves(List<Curve> inputCurve)
		{
			List<Curve> list = new List<Curve>();
			list.AddRange(inputCurve);
			XYZ nearPoint = YJKInspectModelFunc.Utility.CalculateLstCurveMidPoint(inputCurve);
			for (int i = 0; i < list.Count; i++)
			{
				Curve curve = list[i];
				for (int j = 0; j < list.Count; j++)
				{
					if (i != j)
					{
						Curve curve2 = list[j];
						IntersectionResultArray intersectionResultArray;
                        if ((int)curve.Intersect(curve2, out intersectionResultArray) == 8)
						{
							list[i] = YJKSparseDistance.Utility.CutCurvePreserve(curve, curve.Project(intersectionResultArray.get_Item(0).XYZPoint).Parameter, nearPoint);
							list[j] = YJKSparseDistance.Utility.CutCurvePreserve(curve2, curve2.Project(intersectionResultArray.get_Item(0).XYZPoint).Parameter, nearPoint);
						}
					}
				}
			}
			return list;
		}

		public static object CutCurvePreserve(Curve inputCurve, double cutParameter)
		{
			if (inputCurve.GetEndPoint(0).IsAlmostEqualTo(inputCurve.Evaluate(cutParameter, false), double.Parse(Resources.str_feet_OneMM)) || inputCurve.GetEndPoint(1).IsAlmostEqualTo(inputCurve.Evaluate(cutParameter, false), double.Parse(Resources.str_feet_OneMM)))
			{
				return inputCurve;
			}
			Curve curve = inputCurve.Clone();
			curve.MakeBound(curve.GetEndParameter(0), cutParameter);
			Curve curve2 = inputCurve.Clone();
			curve2.MakeBound(cutParameter, curve2.GetEndParameter(1));
			if (curve.Length / curve2.Length >= double.Parse(Resources.Str_CutPreserveValue))
			{
				return curve;
			}
			if (curve2.Length / curve.Length >= double.Parse(Resources.Str_CutPreserveValue))
			{
				return curve2;
			}
			return new List<Curve>
			{
				curve,
				curve2
			};
		}

		public static Curve CutCurvePreserve(Curve inputCurve, double cutParameter, Curve faraWayCurve)
		{
			if (inputCurve.GetEndPoint(0).IsAlmostEqualTo(inputCurve.Evaluate(cutParameter, false), double.Parse(Resources.str_feet_OneMM)) || inputCurve.GetEndPoint(1).IsAlmostEqualTo(inputCurve.Evaluate(cutParameter, false), double.Parse(Resources.str_feet_OneMM)))
			{
				return inputCurve;
			}
			Curve curve = inputCurve.Clone();
			curve.MakeBound(curve.GetEndParameter(0), cutParameter);
			XYZ curveMidPoint = YJKSparseDistance.Utility.GetCurveMidPoint(curve);
			Curve curve2 = inputCurve.Clone();
			curve2.MakeBound(cutParameter, curve2.GetEndParameter(1));
			XYZ curveMidPoint2 = YJKSparseDistance.Utility.GetCurveMidPoint(curve2);
			if (faraWayCurve.Distance(curveMidPoint) > faraWayCurve.Distance(curveMidPoint2))
			{
				return curve;
			}
			return curve2;
		}

		public static Curve CutCurvePreserve(Curve inputCurve, double cutParameter, XYZ nearPoint)
		{
			if (Geometry.IsEqual(inputCurve.GetEndParameter(0), cutParameter) || Geometry.IsEqual(inputCurve.GetEndParameter(1), cutParameter))
			{
				return inputCurve;
			}
			Curve curve = inputCurve.Clone();
			curve.MakeBound(curve.GetEndParameter(0), cutParameter);
			Curve curve2 = inputCurve.Clone();
			curve2.MakeBound(cutParameter, curve2.GetEndParameter(1));
			if (curve2.Distance(nearPoint) < curve.Distance(nearPoint))
			{
				return curve2;
			}
			if (curve2.Distance(nearPoint) > curve.Distance(nearPoint))
			{
				return curve;
			}
			if (inputCurve.GetEndPoint(0).DistanceTo(nearPoint) < inputCurve.GetEndPoint(1).DistanceTo(nearPoint))
			{
				return curve;
			}
			return curve2;
		}

		public static Curve GetAOffestCurveInRoom(Curve inputCurve, Room inputRoom, double offestValue)
		{
			Curve curve = CurveUtility.CreateOffsetCurve(inputCurve, -offestValue);
			YJKSparseDistance.Utility.GetCurveMidPoint(curve);
			Curve curve2 = CurveUtility.CreateOffsetCurve(inputCurve, offestValue);
			YJKSparseDistance.Utility.GetCurveMidPoint(curve2);
			if (null == curve || null == curve2)
			{
				return null;
			}
			bool flag = inputRoom.IsPointInRoom(YJKSparseDistance.Utility.GetCurveMidPoint(curve));
			bool flag2 = inputRoom.IsPointInRoom(YJKSparseDistance.Utility.GetCurveMidPoint(curve2));
			double? subValue = new double?(0.1 * Math.Abs(offestValue));
			if (flag && flag2)
			{
				int? num = YJKSparseDistance.Utility.FindOffestCurveInRoomDriection(inputCurve, inputRoom, offestValue, subValue);
				if (num == null)
				{
					return null;
				}
				if (num.Value > 0)
				{
					return curve;
				}
				return curve2;
			}
			else
			{
				if (flag)
				{
					return curve;
				}
				if (flag2)
				{
					return curve2;
				}
				return null;
			}
		}

		public static int? FindOffestCurveInRoomDriection(Curve inputCurve, Room inputRoom, double offestValue, double? subValue = null)
		{
			if (offestValue < 0.0)
			{
				offestValue = -offestValue;
			}
			if (subValue != null)
			{
				offestValue -= Math.Abs(subValue.Value);
			}
			if (offestValue <= 0.0)
			{
				return null;
			}
			Curve curve = CurveUtility.CreateOffsetCurve(inputCurve, -offestValue);
			YJKSparseDistance.Utility.GetCurveMidPoint(curve);
			Curve curve2 = CurveUtility.CreateOffsetCurve(inputCurve, offestValue);
			YJKSparseDistance.Utility.GetCurveMidPoint(curve2);
			if (null == curve || null == curve2)
			{
				return null;
			}
			bool flag = inputRoom.IsPointInRoom(YJKSparseDistance.Utility.GetCurveMidPoint(curve));
			bool flag2 = inputRoom.IsPointInRoom(YJKSparseDistance.Utility.GetCurveMidPoint(curve2));
			if (subValue != null && (flag && flag2))
			{
				return YJKSparseDistance.Utility.FindOffestCurveInRoomDriection(inputCurve, inputRoom, offestValue, subValue);
			}
			if (flag)
			{
				return new int?(1);
			}
			if (flag2)
			{
				return new int?(-1);
			}
			return null;
		}

		public static List<List<Curve>> DoBoundarySgementSplite(BaseBoundarySegmentPacker input, out Curve boundaryTotalCurve, bool ifIgnorCurveElement = true)
		{
			List<List<Curve>> list = new List<List<Curve>>();
			list.Add(new List<Curve>());
			list.Add(new List<Curve>());
			boundaryTotalCurve = null;
			if (input != null)
			{
				if (input.ThisElement != null && input.ThisElement is Wall && null != input.BoundaryCurve)
				{
					List<List<XYZ>> list2 = new List<List<XYZ>>();
					int num = 0;
					boundaryTotalCurve = input.BoundaryCurve;
					Curve curve = boundaryTotalCurve.Clone();
					curve.MakeUnbound();
					foreach (BaseDoorPacker baseDoorPacker in input.LstDoors)
					{
						list2.Add(new List<XYZ>());
						foreach (XYZ xyz in YJKInspectModelFunc.Utility.GetFamilyInstanceWidthPointAtlWallLocation(baseDoorPacker.ThisDoor, baseDoorPacker.UseTransform, baseDoorPacker.ThisLimitGeometryPacker))
						{
							list2[num].Add(curve.Project(xyz).XYZPoint);
						}
						num++;
					}
					list = YJKSparseDistance.Utility.SplitCurveByPoint(input.BoundaryCurve, list2, true);
				}
				else if ((input.ThisElement == null || !(input.ThisElement is CurveElement) || !ifIgnorCurveElement) && null != input.BoundaryCurve)
				{
					boundaryTotalCurve = input.BoundaryCurve;
					list[1].Add(input.BoundaryCurve);
				}
			}
			return list;
		}

		public static bool IfCurveInRoomByEndPoints(Curve inputCurve, Room inputRoom)
		{
			XYZ endPoint = inputCurve.GetEndPoint(0);
			XYZ endPoint2 = inputCurve.GetEndPoint(1);
			return inputRoom.IsPointInRoom(endPoint) && inputRoom.IsPointInRoom(endPoint2) && inputRoom.IsPointInRoom(YJKSparseDistance.Utility.GetCurveMidPoint(inputCurve));
		}

		public static XYZ GetCurveMidPoint(Curve inputCurve)
		{
			if (!inputCurve.IsBound)
			{
				throw new EvacuationDistanceException(Resources.Exception_ErrorCurve);
			}
			inputCurve.GetEndParameter(0);
			inputCurve.GetEndParameter(1);
			return inputCurve.Evaluate(0.5, true);
		}

		public static List<List<Curve>> SplitCurveByPoint(Curve inputCurve, List<List<XYZ>> inputPoints, bool ifThinkEnd = false)
		{
			List<List<Curve>> list = new List<List<Curve>>();
			list.Add(new List<Curve>());
			list.Add(new List<Curve>());
			List<List<double>> list2 = new List<List<double>>();
			int num = 0;
			foreach (List<XYZ> list3 in inputPoints)
			{
				if (list3.Count > 0)
				{
					list2.Add(new List<double>());
				}
				foreach (XYZ inputPoint in list3)
				{
					double item;
					if (YJKSparseDistance.Utility.IfPointOnCurve(inputCurve, inputPoint, out item))
					{
						list2[num].Add(item);
					}
					else
					{
						list2[num].Add(item);
					}
				}
				num++;
			}
			for (int i = 0; i < list2.Count; i++)
			{
				list2[i] = (from k in list2[i]
				orderby k
				select k).ToList<double>();
			}
			if (list2.Count > 0)
			{
				list2 = (from k in list2
				orderby k[0]
				select k).ToList<List<double>>();
				foreach (List<double> useParameters in list2)
				{
					list[0].AddRange(YJKSparseDistance.Utility.SplitCurveByLstParameter(inputCurve, useParameters, false));
				}
				Curve curve;
				if (ifThinkEnd)
				{
					curve = inputCurve.Clone();
					try
					{
						curve.MakeBound(inputCurve.GetEndParameter(0), list2[0][0]);
						list[1].Add(curve);
					}
					catch (Autodesk.Revit.Exceptions.InvalidOperationException)
					{
					}
				}
				int count;
				for (int j = 0; j < list2.Count - 1; j++)
				{
					count = list2[j].Count;
					curve = inputCurve.Clone();
					try
					{
						curve.MakeBound(list2[j][count - 1], list2[j + 1][0]);
						list[1].Add(curve);
					}
					catch (Autodesk.Revit.Exceptions.InvalidOperationException)
					{
					}
				}
				if (!ifThinkEnd)
				{
					return list;
				}
				count = list2[list2.Count - 1].Count;
				curve = inputCurve.Clone();
				try
				{
					curve.MakeBound(list2[list2.Count - 1][count - 1], inputCurve.GetEndParameter(1));
					list[1].Add(curve);
					return list;
				}
				catch (Autodesk.Revit.Exceptions.InvalidOperationException)
				{
					return list;
				}
			}
			if (ifThinkEnd)
			{
				list[1].Add(inputCurve);
			}
			return list;
		}

		public static List<Curve> SplitCurveByPoint(Curve inputCurve, List<XYZ> inputPoints, bool ifThinkEnd = false)
		{
			List<double> list = new List<double>();
			foreach (XYZ inputPoint in inputPoints)
			{
				double item;
				if (YJKSparseDistance.Utility.IfPointOnCurve(inputCurve, inputPoint, out item))
				{
					list.Add(item);
				}
				else
				{
					list.Add(item);
				}
			}
			return YJKSparseDistance.Utility.SplitCurveByLstParameter(inputCurve, list, ifThinkEnd);
		}

		public static List<Curve> SplitCurveByPoint(Curve inputCurve, XYZ inputPoint)
		{
			List<Curve> list = new List<Curve>();
			double num;
			if (YJKSparseDistance.Utility.IfPointOnCurve(inputCurve, inputPoint, out num))
			{
				Curve curve = inputCurve.Clone();
				Curve curve2 = inputCurve.Clone();
				curve.MakeBound(curve.GetEndParameter(0), num);
				curve2.MakeBound(num, curve2.GetEndParameter(1));
				list.Add(curve);
				list.Add(curve2);
				return list;
			}
			return YJKSparseDistance.Utility.SplitCurveByPoint(inputCurve, inputCurve.Evaluate(num, false));
		}

		public static bool IfPointOnCurve(Curve inputCurve, XYZ inputPoint, out double parameter)
		{
			IntersectionResult intersectionResult = inputCurve.Project(inputPoint);
			parameter = intersectionResult.Parameter;
			return intersectionResult.XYZPoint.IsAlmostEqualTo(inputPoint);
		}

		private static List<Curve> SplitCurveByLstParameter(Curve inputCurve, List<double> useParameters, bool ifThinkEnd = false)
		{
			List<Curve> list = new List<Curve>();
			if (useParameters.Count < 2)
			{
				return list;
			}
			if (ifThinkEnd)
			{
				useParameters.Add(inputCurve.GetEndParameter(0));
				useParameters.Add(inputCurve.GetEndParameter(1));
			}
			useParameters = (from k in useParameters
			orderby k
			select k).ToList<double>();
			for (int i = 0; i < useParameters.Count - 1; i++)
			{
				Curve curve = inputCurve.Clone();
				curve.MakeBound(useParameters[i], useParameters[i + 1]);
				list.Add(curve);
			}
			return list;
		}
	}
}
